#include "LinkItem.h"

namespace Xps
{

	LinkItem::LinkItem(Item* parent, Item* child) : Item(XpsAssets::TreeNode::LINK)
	{
		m_Parent = parent;
		m_Child = child;
		// init shape
		this->setEnabled(false);
		pen.setWidth(2);
		pen.setCapStyle(Qt::RoundCap);
		pen.setJoinStyle(Qt::RoundJoin);
		pen.setColor(QColor(153,185,197,255));
		this->setZValue(-1);
		drawbounds = false;
		setAcceptedMouseButtons(0);
		mode = 0;
		arrow = 0;
	}

	QRectF LinkItem::boundingRect() const
	{
		if (m_Parent == NULL || m_Child == NULL)
			return QRectF(0,0,0,0);

		int x = m_Parent->pos().x()+m_Parent->boundingRect().width()/2;
		int y = m_Parent->pos().y();
		int x2 = m_Child->pos().x()+m_Child->boundingRect().width()/2;
		int y2 = m_Child->pos().y();

		if (x > x2) x = x2;
		if (y > y2) y = y2;

		x-= pen.width();
		y-= pen.width();

		int w = to.x() - from.x();
		int h = to.y() - from.y();
		if (w < 0) w*=-1;
		if (h < 0) h*=-1;
		w+= pen.width()*2+200;
		h+= pen.width()*2+200;

		// rand
		x -= 100;
		y -= 100;
		w += 32;
		h += 32;
		return QRectF(x,y,w,h);
	}

	void LinkItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *item, QWidget *widget)
	{
		painter->setClipRect(item->exposedRect);

		if (m_Parent != 0 && m_Child != 0 && (old_parentpos != m_Parent->scenePos() || old_childpos != m_Child->scenePos()))
		{
			mode = 0;
			arrow = 0;
			prepareGeometryChange();

			old_parentpos = m_Parent->scenePos();
			old_childpos = m_Child->scenePos();
			//
			from.setX(m_Parent->scenePos().x()+m_Parent->boundingRect().width()/2-3);
			from.setY(m_Parent->scenePos().y()+m_Parent->boundingRect().height());
			to.setX(m_Child->scenePos().x()+m_Child->boundingRect().width()/2-3);
			to.setY(m_Child->scenePos().y());

			if (to.y() - from.y() < 50 && ((to.x() - from.x())*(to.x() - from.x())) > 35*35) 
			{
				mode = 1;

				float tox = to.x();
				if (to.x() < from.x())
				{
					to.setX(tox+m_Child->boundingRect().width()/2-2);
					arrow = 2;
				}
				else if (to.x() > from.x())
				{
					to.setX(tox-m_Child->boundingRect().width()/2);
					arrow = 1;
				}
				to.setY(to.y() + m_Child->boundingRect().height()/2-2);
			}

			shape.clear();
			
			shape.append(from);
			// draw corners
			if (from.x() != to.x())
			{
				int halfwayy, halfwayx;
				int xdif = from.x()-to.x(); if (xdif < 0) xdif*=-1;
				int ydif = from.y()-to.y(); if (ydif < 0) ydif*=-1;
				if (from.y() < to.y())
					halfwayy = ydif/2;
				else
					halfwayy = ydif/2 *-1;
				
				if (from.x() < to.x())
				{
					halfwayx = xdif/2; 
					
				}
				else
				{
					halfwayx = xdif/2 *-1;
					
				}

				halfwayy *= 1.38f;
				halfwayx *= 1.38f;
				//if (m_Parent->type() != CONSTRAINT)
				//{
				//}
				if (mode == 0)
				{
					shape.append(QPointF( from.x(), from.y()+halfwayy ));
					shape.append(QPointF( from.x(), from.y()+halfwayy ));

					shape.append(QPointF( to.x(),	to.y()	-halfwayy ));
					shape.append(QPointF( to.x(),	to.y()	-halfwayy ));
				}
				else
				{
					shape.append(QPointF( from.x(), from.y()+halfwayy ));
					shape.append(QPointF( from.x(), from.y()+halfwayy ));

					shape.append(QPointF( to.x()-halfwayx	,	to.y() ));
					shape.append(QPointF( to.x()-halfwayx	,	to.y() ));
				}

			}
			shape.append(to);
			//arrow
			if (mode == 0)
			{
				shape.append(QPointF(to.x()-6, to.y()-9));
				shape.append(QPointF(to.x(), to.y()-2));
				shape.append(QPointF(to.x()+6, to.y()-9));
				shape.append(QPointF(to.x(), to.y()-2));
			}
			else if (mode == 1 && arrow == 2)
			{
				shape.append(QPointF(to.x()+9, to.y()+6));
				shape.append(QPointF(to.x()+2, to.y()));
				shape.append(QPointF(to.x()+9, to.y()-6));
				shape.append(QPointF(to.x()+2, to.y()));
			}
			else
			{
				shape.append(QPointF(to.x()-9, to.y()-6));
				shape.append(QPointF(to.x()-2, to.y()));
				shape.append(QPointF(to.x()-9, to.y()+6));
				shape.append(QPointF(to.x()-2, to.y()));
			}
		}

		QPainterPath roundRectPath;
		if (shape.count() >= 9)
		{
			QPointF p5 = shape.at(5);
			if (mode == 0) p5.setY(p5.y()-9);
			if (mode == 1 && arrow == 1) p5.setX(p5.x()-9);
			if (mode == 1 && arrow == 2) p5.setX(p5.x()+9);
			roundRectPath.moveTo(shape.at(0));
			roundRectPath.cubicTo(shape.at(1), shape.at(3), p5);
			roundRectPath.moveTo(shape.at(6));
			roundRectPath.lineTo(shape.at(7));
			roundRectPath.lineTo(shape.at(8));


			painter->setPen(pen);
			painter->drawPath(roundRectPath);
		}
		else
		{
			QPointF p1 = shape.at(1);
			p1.setY(p1.y()-9);
			roundRectPath.moveTo(shape.at(0));
			roundRectPath.lineTo(p1);
			roundRectPath.moveTo(shape.at(2));
			roundRectPath.lineTo(shape.at(3));
			roundRectPath.lineTo(shape.at(4));
			painter->setPen(pen);
			painter->drawPath(roundRectPath);
		}

		// drawbounds
		if (drawbounds)
		{
			pen.setColor(QColor(200,0,0));
			painter->setPen(pen);
			painter->drawRect(boundingRect());
		}
	}


}